package com.the_last.service;

import com.the_last.constant.ReservationConstant;
import com.the_last.constant.RedisKeyConstant;
import com.the_last.mapper.ReservationMapper;
import com.the_last.pojo.po.Reservation;
import com.the_last.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 预约超时处理服务
 * 处理预约超时的业务逻辑
 * 
 * @author zhanghaifeng
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ReservationTimeoutService {
    
    private final ReservationMapper reservationMapper;
    private final RedisUtil redisUtil;
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 处理预约超时逻辑
     * 
     * @param reservationId 预约ID
     * @param messageId 消息唯一标识（用于防重复消费）
     * @return 是否处理成功
     */
    public boolean processReservationTimeout(Long reservationId, String messageId) {
        String currentTime = LocalDateTime.now().format(FORMATTER);
        log.info("[{}] 开始处理预约超时，预约ID: {}, 消息ID: {}", currentTime, reservationId, messageId);
        
        try {
            // 检查Redis中是否已处理过该消息，防止重复消费
            String redisKey = ReservationConstant.RESERVATION_TIMEOUT_MESSAGE_KEY_PREFIX + messageId;
            if (redisUtil.get(redisKey) != null) {
                log.warn("消息已处理过，跳过重复消费，消息ID: {}", messageId);
                return true;
            }
            
            // 查询预约信息
            Reservation reservation = reservationMapper.selectById(reservationId);
            if (reservation == null) {
                log.warn("预约不存在，预约ID: {}", reservationId);
                // 设置处理标识，避免重复处理
                redisUtil.set(redisKey, "processed", ReservationConstant.RESERVATION_MESSAGE_EXPIRE_SECONDS);
                return false;
            }
            
            log.info("查询到预约信息，预约状态: {}, 预约日期: {}, 申请时间: {}", 
                    reservation.getStatus(), reservation.getReservationDate(), reservation.getApplyTime());
            
            // 检查预约状态，只有待使用的预约才需要超时处理
            if (!ReservationConstant.STATUS_PENDING.equals(reservation.getStatus())) {
                log.info("预约状态不是待使用状态，无需超时处理，当前状态: {}", reservation.getStatus());
                // 设置处理标识
                redisUtil.set(redisKey, "processed", ReservationConstant.RESERVATION_MESSAGE_EXPIRE_SECONDS);
                return true;
            }
            
            // 更新预约状态为超时
            reservation.setStatus(ReservationConstant.STATUS_TIMEOUT);
            
            int updateCount = reservationMapper.updateById(reservation);
            if (updateCount > 0) {
                log.info("预约超时处理成功，预约ID: {} 已设置为超时状态", reservationId);
                
                // 设置处理标识
                redisUtil.set(redisKey, "processed", ReservationConstant.RESERVATION_MESSAGE_EXPIRE_SECONDS);
                return true;
            } else {
                log.error("更新预约状态失败，预约ID: {}", reservationId);
                return false;
            }
            
        } catch (Exception e) {
            log.error("处理预约超时失败，预约ID: {}, 消息ID: {}", reservationId, messageId, e);
            return false;
        }
    }
    
    /**
     * 检查预约状态变更是否合法
     * 
     * @param currentStatus 当前状态
     * @param newStatus 新状态
     * @return 是否合法
     */
    public boolean isValidStatusChange(Integer currentStatus, Integer newStatus) {
        if (currentStatus == null || newStatus == null) {
            return false;
        }
        
        // 待使用状态可以变更为已取消、已使用或超时
        if (ReservationConstant.STATUS_PENDING.equals(currentStatus)) {
            return ReservationConstant.STATUS_CANCELLED.equals(newStatus) ||
                   ReservationConstant.STATUS_USED.equals(newStatus) ||
                   ReservationConstant.STATUS_TIMEOUT.equals(newStatus);
        }
        
        // 其他状态不允许变更
        return false;
    }
    
    /**
     * 获取状态描述
     * 
     * @param status 状态值
     * @return 状态描述
     */
    public String getStatusDescription(Integer status) {
        if (status == null) {
            return "未知";
        }
        
        switch (status) {
            case 0:
                return "已取消";
            case 1:
                return "待使用";
            case 2:
                return "已使用";
            case 3:
                return "已超时";
            default:
                return "未知状态(" + status + ")";
        }
    }
}